home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Celestin Apprentice 5
/
Apprentice-Release5.iso
/
Source Code
/
C
/
System
/
ScreenDaemon 1.2
/
ScreenDaemon appe
/
SDinit.c
< prev
next >
Wrap
C/C++ Source or Header
|
1996-03-16
|
13KB
|
469 lines
/*********************************************************************
* ScreenDaemon INIT
*********************************************************************/
#include <Displays.h>
#include "gamma.h"
#include "SD.h"
#include "SDinit.h"
#define Bail() { SysBeep(5); SysBeep(5); return false; }
void main()
{
Ptr patchPtr;
PatchGlobalsPtr pgPtr;
long codeSize, offset, result, oldA5;
PrefStructureHandle prefHandle;
Handle procH;
Boolean usingPrefsFile;
short theResFile;
fQDGlobals fqd;
GrafPort gp;
GDHandle theScreen;
Rect theRect;
/* Are we likely to be able to run? */
if (Gestalt('sysv', &result) != noErr || result < 0x700) {
DisplayIcon(kErrorIcon);
return; /* We're pre-System 7, so our 'appe' won't likely load. Give up now. */
}
if (!IsGammaAvailable()) {
DisplayIcon(kErrorIcon);
return; /* we can't do a gamma fade, so we can't run */
}
/* try and get some memory in the system heap for code and globals */
codeSize = (long) EndPatchCode - (long) StartPatchCode;
patchPtr = NewPtrSys(codeSize + sizeof(PatchGlobals));
if (!patchPtr) {
DisplayIcon(kErrorIcon);
return; /* out of memory -- abort patching */
}
/* Set up pgPtr */
pgPtr = (PatchGlobalsPtr) patchPtr;
/* Reset pgPtr->pgVersion for use as a watch variable */
pgPtr->pgVersion = 0;
/* Open up the preferences file */
theResFile = CurResFile();
usingPrefsFile = OpenPrefsFile();
/* if usingPrefsFile == false then we're opening our internal prefs */
prefHandle = (PrefStructureHandle) GetIndResource('PREF', 1);
if (ResError() == noErr) {
pgPtr->pgVersion = (**prefHandle).version;
pgPtr->pgMustSleep = false;
pgPtr->pgSleepRect = (**prefHandle).sleepNowCorner;
pgPtr->pgWakeRect = (**prefHandle).sleepNeverCorner;
pgPtr->pgIdleTicks = ((long) (**prefHandle).idleTime) * 3600;
pgPtr->pgMinBrite = (**prefHandle).refreshSeconds;
pgPtr->pgMustSave = (**prefHandle).saverOn;
pgPtr->pgForceUpdates = (**prefHandle).forceUpdates;
ReleaseResource((Handle) prefHandle);
if (usingPrefsFile) {
CloseResFile(CurResFile());
UseResFile(theResFile);
}
}
/* Double check to see if stuff *really* loaded */
if (pgPtr->pgVersion == 0) {
DisposPtr(patchPtr);
DisplayIcon(kErrorIcon);
return; /* can't read in preferences - abort patching */
}
/* initialize the patch globals at the beginning of the block */
pgPtr->pgOldSE = (SEProcPtr) GetTrapAddress(_SystemEvent);
/* move the code into place after the globals */
BlockMove(StartPatchCode, patchPtr + sizeof(PatchGlobals), codeSize);
/* move to the next routine */
patchPtr += sizeof(PatchGlobals);
offset = (long) MySystemEvent - (long) StartPatchCode;
/* make a UniversalProcedurePointer for the SystemEvent patch */
pgPtr->pgMySystemEventUPP = NewRoutineDescriptor((ProcPtr) ((long) patchPtr + (long) offset),
kPascalStackBased, kM68kISA);
/* set the SystemEvent patch */
SetToolTrapAddress(pgPtr->pgMySystemEventUPP, _SystemEvent);
/* install a new 'sDmn' gestalt selector */
offset = (long) sDmnSelector - (long) StartPatchCode;
pgPtr->pgMysDmnSelectUPP = NewRoutineDescriptor((ProcPtr) ((long) patchPtr + (long) offset),
uppSelectorFunctionProcInfo, kM68kISA);
NewGestalt('sDmn', (SelectorFunctionUPP) pgPtr->pgMysDmnSelectUPP);
/* install a new 'SAVR' gestalt selector */
offset = (long) SAVRSelector - (long) StartPatchCode;
pgPtr->pgMySAVRSelectUPP = NewRoutineDescriptor((ProcPtr) ((long) patchPtr + (long) offset),
uppSelectorFunctionProcInfo, kM68kISA);
NewGestalt('SAVR', (SelectorFunctionUPP) pgPtr->pgMySAVRSelectUPP);
/* install a new 'SAVC' gestalt selector */
offset = (long) SAVCSelector - (long) StartPatchCode;
pgPtr->pgMySAVCSelectUPP = NewRoutineDescriptor((ProcPtr) ((long) patchPtr + (long) offset),
uppSelectorFunctionProcInfo, kM68kISA);
NewGestalt('SAVC', (SelectorFunctionUPP) pgPtr->pgMySAVCSelectUPP);
pgPtr->pgSaverOn = false;
pgPtr->pgMustSleep = false;
pgPtr->pgMustWake = false;
pgPtr->pgInSleepRect = false;
pgPtr->pgLastAction = LMGetTicks();
/* if we got this far, put up the appropriate icon */
if (usingPrefsFile == false) {
DisplayIcon(kPrefIcon);
} else {
DisplayIcon(pgPtr->pgMustSave == true ? kNormalIcon : kOffIcon);
}
}
/*********************************************************************
* OpenPrefsFile:
*
* Open up our prefs file. If there are problems, then create a new
* prefs file. (Also in ScreenDaemon Control.c)
*
*********************************************************************/
Boolean OpenPrefsFile()
{
FSSpec theSpec;
OSErr fsErr;
long result;
short resAttrs, theResFile, thePrefsFile;
Handle prefHandle, tmplHandle, stringHandle; /* FIXME - use just one handle! */
Str255 theString;
/* Check to see if FindFolder is available */
if ((Gestalt(gestaltFindFolderAttr, &result) != noErr) ||
!(result & Bit(gestaltFindFolderPresent)))
return false;
/* See if we can find the preferences folder */
if (FindFolder(kOnSystemDisk, kPreferencesFolderType, kCreateFolder,
&(theSpec.vRefNum), &(theSpec.parID)) != noErr)
return false;
/* Get the file name */
stringHandle = GetIndResource('STR ', 1);
if (ResError() != noErr)
return false;
BlockMoveData(*stringHandle, theString, 256);
ReleaseResource(stringHandle);
/* Make a file specification */
switch (FSMakeFSSpec(theSpec.vRefNum, theSpec.parID, theString, &theSpec)) {
/* We need to create the file */
case fnfErr:
/* make a new file */
FSpCreateResFile(&theSpec, 'sDmn', 'pref', smSystemScript);
if (ResError() != noErr)
return false;
/* Open it, and copy over our default resources */
theResFile = CurResFile();
thePrefsFile = FSpOpenResFile(&theSpec, fsRdWrPerm);
/* If we can't open the freshly created file, punt */
if (ResError() != noErr)
return false;
/* We're open... copy away */
/* Get preferences resource */
UseResFile(theResFile);
prefHandle = GetIndResource('PREF', 1);
resAttrs = GetResAttrs(prefHandle);
DetachResource(prefHandle);
/* Get the name of our prefs resource */
stringHandle = GetIndResource('STR ', 2);
if (ResError() != noErr)
return false;
BlockMoveData(*stringHandle, theString, 256);
ReleaseResource(stringHandle);
/* Write preferences resource */
UseResFile(thePrefsFile);
AddResource(prefHandle, 'PREF', 128, theString);
SetResAttrs(prefHandle, resAttrs);
ChangedResource(prefHandle);
WriteResource(prefHandle);
ReleaseResource(prefHandle);
/* Get template resource */
UseResFile(theResFile);
tmplHandle = GetIndResource('TMPL', 1);
resAttrs = GetResAttrs(tmplHandle);
DetachResource(tmplHandle);
/* Get the name of our prefs resource */
stringHandle = GetIndResource('STR ', 3);
if (ResError() != noErr)
return false;
BlockMoveData(*stringHandle, theString, 256);
ReleaseResource(stringHandle);
/* Write template resource */
UseResFile(thePrefsFile);
AddResource(tmplHandle, 'TMPL', 128, theString);
SetResAttrs(tmplHandle, resAttrs);
ChangedResource(tmplHandle);
WriteResource(tmplHandle);
ReleaseResource(tmplHandle);
/* All done */
return true;
break;
/* Everything went fine - open the file */
case noErr:
FSpOpenResFile(&theSpec, fsRdPerm);
return true;
break;
/* We don't handle any other errors */
default:
return false;
break;
}
/* This will never execute, because we'll never get here */
return false;
}
/*********************************************************************
* DisplayIcon:
*
* Put up the appropriate icon.
*
*********************************************************************/
void DisplayIcon(short iconID)
{
typedef pascal short (*ShowInitProcPtr) (short,short);
Handle procH;
ShowInitProcPtr ShowInitProc;
/* Load in the ShowInit PROC and call it */
if ((procH = GetIndResource('PROC', 1)) != 0L) {
HLock(procH);
ShowInitProc = (ShowInitProcPtr) *procH;
(*ShowInitProc) (iconID, -1);
HUnlock(procH);
ReleaseResource(procH);
}
}
/*********************************************************************
* StartPatchCode:
*
* Dummy proc to mark the beginning of the code for the
* patches. Make sure all of your patch code is between
* here and EndPatchCode.
*
*********************************************************************/
void StartPatchCode()
{
}
/*********************************************************************
* MySystemEvent:
*
* Tail patch on SystemEvent.
*
* If you want to eat the event (not pass it on to the caller) then set
* returnValue to true.
*
*********************************************************************/
pascal short MySystemEvent(EventRecord *theEvent)
{
PatchGlobalsPtr pgPtr;
short returnValue;
/* register short foo; */
short foo; /* Was the register assignment causing us problems? */
/* find our globals */
pgPtr = (PatchGlobalsPtr) ((long) StartPatchCode - sizeof(PatchGlobals));
/* call original SE first */
returnValue = (*pgPtr->pgOldSE) (theEvent);
if ((foo = theEvent->what) >= 1 && foo <= 5 || foo == 7) {
pgPtr->pgLastAction = LMGetTicks(); /* Update last time counter */
pgPtr->pgInSleepRect = false;
if (pgPtr->pgSaverOn) {
if (foo != 7) { /* Mask keypresses and clicks */
/* but allow disk mounts. (disk == 7) */
returnValue = true; /* We've "handled" the event. */
theEvent->what = 0;
}
pgPtr->pgMustWake = true;
}
}
/* return to original caller */
return returnValue;
}
/*********************************************************************
* sDmnSelector:
*
* 'sDmn' gestalt selector that provides the address of our patch
* globals. This is *much* cleaner than patching SizeResource().
*
*********************************************************************/
pascal void sDmnSelector(OSType selector, long *result)
{
/* find our globals ...and give 'em back! */
*result = (long) ((long) StartPatchCode - sizeof(PatchGlobals));
}
/*********************************************************************
* SAVRSelector:
*
* 'SAVR' gestalt selector that tells the world when we're alive and
* also when we're sleeping.
*
*********************************************************************/
pascal void SAVRSelector(OSType selector, long *result)
{
PatchGlobalsPtr pgPtr;
/* find our globals */
pgPtr = (PatchGlobalsPtr) ((long) StartPatchCode - sizeof(PatchGlobals));
*result = 0;
/* if we haven't been disabled, tell the world of our presence */
if (pgPtr->pgMustSave == true)
*result |= Bit(gestaltSaverTurnedOn); // saver enabled
/* If screen is darkened, tell the world we're alive */
if (pgPtr->pgSaverOn == true) {
*result |= Bit(gestaltSaverAsleep); // saver asleep
}
}
/*********************************************************************
* SAVCSelector:
*
* The 'SAVC' gestalt selector passes back the address of our control
* routine so that other applications can control us.
*
* We can be turned on and off remotely, and we can be told to put
* the screen to sleep and wake the screen up. Neat, huh?
*
*********************************************************************/
pascal void SAVCSelector(OSType selector, long *result)
{
*result = (long) SaverControl;
}
/*********************************************************************
* SaverControl:
*
* Executes a command from an application or whatever.
*
*********************************************************************/
pascal OSErr SaverControl(short theCommand)
{
PatchGlobalsPtr pgPtr;
/* find our globals */
pgPtr = (PatchGlobalsPtr) ((long) StartPatchCode - sizeof(PatchGlobals));
switch (theCommand) {
case eSaverWakeUp: // Make ScreenDaemon wake up.
if (pgPtr->pgSaverOn)
pgPtr->pgMustWake = true;
break;
case eSaverSleep: // Make ScreenDaemon go to sleep.
if (pgPtr->pgMustSave)
pgPtr->pgMustSleep = true;
break;
case eSaverOn: // Turn ScreenDaemon on.
pgPtr->pgMustSave = true;
pgPtr->pgMustSleep = false;
break;
case eSaverOff: // Turn ScreenDaemon off.
if (pgPtr->pgSaverOn)
pgPtr->pgMustWake = true;
pgPtr->pgMustSave = false;
break;
}
return noErr;
}
/*********************************************************************
* EndPatchCode:
*
* Dummy proc to mark the end of the code for the patches.
* Make sure all of your patch code is between here and
* StartPatchCode.
*
*********************************************************************/
void EndPatchCode()
{
}
/*********************************************************************
* IsGammaAvailable:
*
* Tests availability of gamma fading support.
*
*********************************************************************/
pascal Boolean IsGammaAvailable()
{
GDHandle theGDevice;
if (NGetTrapAddress(kGetDeviceListTrapNum, ToolTrap) ==
NGetTrapAddress(_Unimplemented, ToolTrap)) return(FALSE);
for(theGDevice = GetDeviceList(); theGDevice; theGDevice = GetNextDevice(theGDevice)) {
if (TestDeviceAttribute(theGDevice, screenDevice) &&
TestDeviceAttribute(theGDevice, noDriver)) return(FALSE);
if ((*theGDevice)->gdType == fixedType) return(FALSE);
}
return(TRUE);
}